#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
#include <sstream>
#include <iostream>
#include "SDL/SDL_ttf.h"
#include "MyTimer.h"

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

const int FRAMES_PER_SECOND = 10;

int frame = 0;
bool cap = true;
MyTimer fps;
MyTimer update;

// The portions of the Sprite map to be blitted
SDL_Rect clip[8];

// Surfaces
SDL_Surface *screen = NULL;
SDL_Surface *message = NULL;
SDL_Surface *background = NULL;
SDL_Surface *cats = NULL;
SDL_Surface *text = NULL;
SDL_Surface *upMessage = NULL;
SDL_Surface *downMessage = NULL;
SDL_Surface *leftMessage = NULL;
SDL_Surface *rightMessage = NULL;


// The event structure that will be used
SDL_Event event;

// The font that will be used
TTF_Font* font = NULL;
TTF_Font* darkFont = NULL;

// The color of the font
SDL_Color textColor = { 255, 255, 255 };

SDL_Surface *load_image(std::string filename, bool colorStrip = false) {
	// Temporary storage for loaded image
	SDL_Surface *loadedImage = NULL;

	// Optimized image
	SDL_Surface *optimizedImage = NULL;

	loadedImage = IMG_Load(filename.c_str());

	if (loadedImage != NULL) {
		// Create optimized image
		optimizedImage = SDL_DisplayFormat(loadedImage);

		// Free old image
		SDL_FreeSurface(loadedImage);
	}

	if (optimizedImage != NULL && colorStrip) {
		// Map the color key
		Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 0xFF, 0xFF, 0xFF);

		// Set all pixels of color R 0xFF, G 0xFF, B 0xFF to be transparent
		SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);
	}

	return optimizedImage;

}

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL) {
	// Make temp rectangle to hold offsets
	SDL_Rect offset;

	offset.x = x;
	offset.y = y;

	SDL_BlitSurface(source, clip, destination, &offset);
}

bool init() {
	if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
		return false;
	}

	// Set up the screen
	screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);

	// If there was an error in setting up the screen
	if (screen == NULL) {
		return false;
	}

	if (TTF_Init() == -1) {
		return false;
	}

	// Set the window caption
	SDL_WM_SetCaption("TTF Test", NULL);

	return true;
}

bool load_files() {
	// Load the images
	message = load_image("src/hello.bmp", true);
	background = load_image("src/LAND2.BMP");
	cats = load_image("src/runningcat.png", true);

	font = TTF_OpenFont("src/Outwrite.ttf", 28);
	darkFont = TTF_OpenFont("src/DarkistheNight.ttf", 22);

	if (message == NULL || background == NULL || cats == NULL || font == NULL) {
		return false;
	}

	return true;

}

void clean_up() {
	//Free the loaded image
	SDL_FreeSurface( message );
	SDL_FreeSurface( background );
	SDL_FreeSurface( cats );
	SDL_FreeSurface( text );

	TTF_CloseFont( font );

	TTF_Quit();

	//Quit SDL
	SDL_Quit();
}

int main( int argc, char* args[] ) {

	clip[0].x = 0;
	clip[0].y = 0;
	clip[0].w = 512;
	clip[0].h = 256;

	clip[1].x = 512;
	clip[1].y = 0;
	clip[1].w = 512;
	clip[1].h = 256;

	clip[2].x = 0;
	clip[2].y = 256;
	clip[2].w = 512;
	clip[2].h = 256;

	clip[3].x = 512;
	clip[3].y = 256;
	clip[3].w = 512;
	clip[3].h = 256;

	clip[4].x = 0;
	clip[4].y = 512;
	clip[4].w = 512;
	clip[4].h = 256;

	clip[5].x = 512;
	clip[5].y = 512;
	clip[5].w = 512;
	clip[5].h = 256;

	clip[6].x = 0;
	clip[6].y = 768;
	clip[6].w = 512;
	clip[6].h = 256;

	clip[7].x = 512;
	clip[7].y = 768;
	clip[7].w = 512;
	clip[7].h = 256;

	// Make sure the program waits for a quit
	bool quit = false;

	// Initialize
	if (init() == false) {
		return 1;
	}

	// Load the files
	if (load_files() == false) {
		return 1;
	}

	// Render the text
	text = TTF_RenderText_Solid( font, "See The Fat cat Run!", textColor );

	// Render the messages
	upMessage = TTF_RenderText_Solid( font, "up", textColor );
	downMessage = TTF_RenderText_Solid( font, "down", textColor );
	leftMessage = TTF_RenderText_Solid( font, "left", textColor );
	rightMessage = TTF_RenderText_Solid( font, "right", textColor );

	message == NULL;

	if (text == NULL) {
		return 1;
	}

	// Apply the background to the screen
	apply_surface(0, 0, background, screen);

	apply_surface(0, 0, cats, screen, &clip[0]);

	apply_surface(0, 0, text, screen);

	//Update Screen
	if (SDL_Flip( screen ) == -1) {
		return 1;
	}

	int count = 0;

	bool firstQuit = true;
	while (!quit) {
		// Start the timer
		fps.start();
		update.start();
		while (SDL_PollEvent(&event)) {
			// If the user has Xed out
			if (event.type == SDL_QUIT) {
				if (firstQuit) {
					firstQuit = false;
					text = TTF_RenderText_Solid(darkFont, "run, run, run, as fast as you can, you can't X me, I'm the Gingerbread Cat!", textColor);
				}
				else {
					// Quit the program
					quit = true;
				}
			}
		}

		if (count > 7) {
			count = 0;
		}

		apply_surface(0, 0, background, screen);
		apply_surface((SCREEN_WIDTH - text->w) / 2, 20, text, screen);
		apply_surface(0, 222, cats, screen, &clip[count]);


		Uint8 *keystates = SDL_GetKeyState(NULL);

		if (keystates[ SDLK_UP ]) {
			apply_surface((SCREEN_WIDTH - upMessage->w) / 2, 75, upMessage, screen);
		}
		if (keystates[ SDLK_DOWN ]) {
			apply_surface((SCREEN_WIDTH - downMessage->w) / 2, 175, downMessage, screen);
		}
		if (keystates[ SDLK_LEFT ]) {
			apply_surface((SCREEN_WIDTH - leftMessage->w) / 4, 125, leftMessage, screen);
		}
		if (keystates[ SDLK_RIGHT ]) {
			apply_surface((SCREEN_WIDTH - rightMessage->w) * 3 / 4, 125, rightMessage, screen);
		}

		//Update Screen
		if (SDL_Flip( screen ) == -1) {
			return 1;
		}
		frame++;

		//If we want to cap the framerate
		if (fps.get_ticks() < 1000 / FRAMES_PER_SECOND) {
			// Sleep during the remainig time
			SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks());
		}
		//SDL_Delay(100);
		//		if (update.get_ticks() > 1000) {
		//			std::stringstream caption;
		//			caption << "Average Frames Per Second: " << frame / (fps.get_ticks() / 1000);
		//
		//			SDL_WM_SetCaption(caption.str().c_str(), NULL);
		//
		//			update.stop();
		//			update.start();
		//		}
		count++;
	}
	clean_up();

	return 0;
}
